---------------Rhyme Land--------------
A 4am crack                  2017-09-04
---------------------------------------

Name: Rhyme Land
Genre: educational
Year: 1985
Credits: Mindflight, Inc.
Publisher: Grolier Publishing
Platform: Apple ][+ or later
Media: single-sided 5.25-inch floppy
OS: Diversi-DOS C1983
Previous cracks: none
Identical cracks:
  #1399 The Story of Miss Mouse

                   ~

               Chapter 0
 In Which Various Automated Tools Fail
          In Interesting Ways


COPYA
  read error on first pass

Locksmith Fast Disk Backup
  unable to read track $03

EDD 4 bit copy (no sync, no count)
  no errors, but copy boots DOS, loads
  a startup program, then prints "DISK
  IS DEFECTIVE" and exits with no DOS
  in memory

Copy ][+ nibble editor
  track $03 is almost entirely sync
  bytes, with the occasional $D5 nibble
  (almost certainly a protection track)

Disk Fixer
  entire disk is standard except T03
  T00,S00 -> DOS 3.3 bootloader
  T01,S09 -> startup program is "MIND"
  standard DOS 3.3 disk catalog on T11

Why didn't any of my copies work?
  specially formatted nibble sequence
  on track $03, designed to fool even
  the best bit copiers

Next steps:

  1. Find the protection check that is
     reading track $03
  2. Disable it
  3. Declare victory (*)

(*) go to the gym

                   ~

               Chapter 1
         In Which We Get Lucky


Booting my non-working copy, it loads
DOS, runs a startup program, then hangs
with the drive motor running. Somewhat
surprisingly, <Ctrl-Reset> gets me to a
working prompt.

<Ctrl-Reset>

]CALL -151

; location of last binary file loaded
*AA72.AA73

AA72- 35 86

*8635L

; oh look, a bunch of self-modifying
; code that has already modified itself
8635-   4E 38 86    LSR   $8638
8638-   6E 3B 86    ROR   $863B
863B-   A2 53       LDX   #$53
863D-   6E 40 86    ROR   $8640
8640-   6E 4D 86    ROR   $864D
8643-   6E 46 86    ROR   $8646
8646-   6E 50 86    ROR   $8650
8649-   6E 51 86    ROR   $8651
864C-   38          SEC

; apparently we have already decrypted
; the following code as well THIS IS
; THE MOST CONVENIENT PROTECTION CHECK
; I'VE EVER STUMBLED INTO
864D-   7E 35 86    ROR   $8635,X
8650-   E8          INX
8651-   D0 FA       BNE   $864D

; save some RWTS parameters on the
; stack
8653-   AD EC B7    LDA   $B7EC
8656-   48          PHA
8657-   AD F4 B7    LDA   $B7F4
865A-   48          PHA

; seek to track $03 (the unreadable
; track!)
865B-   A9 03       LDA   #$03
865D-   8D EC B7    STA   $B7EC
8660-   A9 00       LDA   #$00
8662-   8D F4 B7    STA   $B7F4
8665-   A0 E8       LDY   #$E8
8667-   A9 B7       LDA   #$B7
8669-   20 B5 B7    JSR   $B7B5

; turn on drive motor manually
866C-   BD 89 C0    LDA   $C089,X

; restore RWTS parameters
866F-   68          PLA
8670-   8D F4 B7    STA   $B7F4
8673-   68          PLA
8674-   8D EC B7    STA   $B7EC

; find $D5 nibble
8677-   BD 8C C0    LDA   $C08C,X
867A-   10 FB       BPL   $8677
867C-   48          PHA
867D-   68          PLA
867E-   C9 D5       CMP   #$D5
8680-   D0 F5       BNE   $8677

; initialize a checksum
8682-   A0 00       LDY   #$00
8684-   8C F0 86    STY   $86F0

; count number of $F7 nibbles before
; another $D5 nibble
8687-   BD 8C C0    LDA   $C08C,X
868A-   10 FB       BPL   $8687
868C-   C9 D5       CMP   #$D5
868E-   F0 0F       BEQ   $869F
8690-   C9 F7       CMP   #$F7
8692-   D0 01       BNE   $8695
8694-   C8          INY

; the sum of the nibbles themselves
; constitutes the checksum
8695-   18          CLC
8696-   6D F0 86    ADC   $86F0
8699-   8D F0 86    STA   $86F0
869C-   4C 87 86    JMP   $8687
869F-   98          TYA
86A0-   F0 E0       BEQ   $8682

; skip $FF nibbles
86A2-   BD 8C C0    LDA   $C08C,X
86A5-   10 FB       BPL   $86A2
86A7-   48          PHA
86A8-   68          PLA
86A9-   C9 FF       CMP   #$FF
86AB-   F0 F5       BEQ   $86A2

; if next nibble is $D5, fail
86AD-   C9 D5       CMP   #$D5
86AF-   F0 31       BEQ   $86E2

; skip several more nibbles
86B1-   A0 05       LDY   #$05
86B3-   BD 8C C0    LDA   $C08C,X
86B6-   10 FB       BPL   $86B3
86B8-   48          PHA
86B9-   68          PLA
86BA-   88          DEY
86BB-   D0 F6       BNE   $86B3

; skip $FF nibbles
86BD-   BD 8C C0    LDA   $C08C,X
86C0-   10 FB       BPL   $86BD
86C2-   48          PHA
86C3-   68          PLA
86C4-   C9 FF       CMP   #$FF
86C6-   F0 F5       BEQ   $86BD

; if next nibble is not $D5, fail
86C8-   C9 D5       CMP   #$D5
86CA-   D0 16       BNE   $86E2

; skip $FF nibbles
86CC-   BD 8C C0    LDA   $C08C,X
86CF-   10 FB       BPL   $86CC
86D1-   C9 FF       CMP   #$FF
86D3-   D0 0D       BNE   $86E2

; verify checksum, branch on failure
86D5-   AD F0 86    LDA   $86F0
86D8-   C9 10       CMP   #$10
86DA-   D0 06       BNE   $86E2

; success path falls through to here --
; turn off drive motor and continue
; elsewhere
86DC-   BD 88 C0    LDA   $C088,X
86DF-   4C 36 87    JMP   $8736

*8736L

; wipe the protection code from memory
8736-   A9 00       LDA   #$00
8738-   A8          TAY
8739-   99 35 86    STA   $8635,Y
873C-   C8          INY
873D-   D0 FA       BNE   $8739

; and exit gracefully
873F-   60          RTS

There are no side effects; even the
checksum in $86F0 is wiped clean before
returning to the caller.

Meanwhile, in The Badlands...

*86E2L

; copy the next routine to lower memory
86E2-   A0 50       LDY   #$50
86E4-   B9 F1 86    LDA   $86F1,Y
86E7-   99 00 03    STA   $0300,Y
86EA-   88          DEY
86EB-   10 F7       BPL   $86E4

; and continue from there
86ED-   4C 00 03    JMP   $0300

; (executed from $0300)
; turn off drive motor
86F1-   BD 88 C0    LDA   $C088,X

; wipe main memory
86F4-   A0 00       LDY   #$00
86F6-   A2 B8       LDX   #$B8
86F8-   99 00 BF    STA   $BF00,Y
86FB-   88          DEY
86FC-   D0 FA       BNE   $86F8
86FE-   CE 09 03    DEC   $0309
8701-   CA          DEX
8702-   8A          TXA
8703-   D0 F3       BNE   $86F8

; text mode
8705-   AD 54 C0    LDA   $C054
8708-   AD 51 C0    LDA   $C051
870B-   AD 81 C0    LDA   $C081
870E-   20 93 FE    JSR   $FE93
8711-   20 89 FE    JSR   $FE89
8714-   20 58 FC    JSR   $FC58

; print error message (below)
8717-   A0 10       LDY   #$10
8719-   B9 34 03    LDA   $0334,Y
871C-   99 08 07    STA   $0708,Y
871F-   88          DEY
8720-   10 F7       BPL   $8719

; exit via BASIC
8722-   4C 00 E0    JMP   $E000

; error message in ASCII
8725-   "DISK IS DEFECTIVE"

(This is the behavior I saw on my non-
working EDD bit copy.)

                   ~

               Chapter 2
          In Which Stay Lucky


Turning again to my Disk Fixer sector
editor, I search the disk for the first
few bytes of the protection code
("4E 38 86", the "LSR $8638" at $8635)
and find it on track $05. Copy II Plus
says this is the first sector of the
file named "THING2", which starts at
$8635, so that lines up with what I saw
earlier.

Replacing the first byte with an "RTS"
will bypass the entire thing.

T05,S0C,$04: 4E -> 60

]PR#6
...works...

Quod erat liberandum.

---------------------------------------
A 4am crack                    No. 1400
------------------EOF------------------
